package com.hzyl.famousreader.view.activity;

import android.Manifest;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.view.Gravity;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.blankj.utilcode.util.*;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.liulishuo.okdownload.DownloadTask;
import com.liulishuo.okdownload.core.cause.EndCause;
import com.liulishuo.okdownload.core.listener.DownloadListener2;
import com.umeng.analytics.MobclickAgent;
import com.hzyl.famousreader.R;
import com.hzyl.famousreader.databinding.ActivityReadBinding;
import com.hzyl.famousreader.repository.persistence.entity.Book;
import com.hzyl.famousreader.repository.persistence.entity.BookChapter;
import com.hzyl.famousreader.repository.webservice.cache.Resource;
import com.hzyl.famousreader.router.Router;
import com.hzyl.famousreader.util.BrightnessUtils;
import com.hzyl.famousreader.view.adapter.ReadBgAdapter;
import com.hzyl.famousreader.view.adapter.ReadCategoryAdapter;
import com.hzyl.famousreader.view.widget.core.ReadSettingManager;
import com.hzyl.famousreader.view.widget.core.ReadThemeEnum;
import com.hzyl.famousreader.view.widget.core.animation.AnimModeEnum;
import com.hzyl.famousreader.view.widget.core.loader.DataLoader;
import com.hzyl.famousreader.view.widget.core.loader.SplitDataLoader;
import com.hzyl.famousreader.view.widget.core.model.Chapter;
import com.hzyl.famousreader.view.widget.core.model.ReadBackground;
import com.hzyl.famousreader.viewmodel.BookViewModel;

import java.io.File;
import java.util.*;

/**
 * 阅读器
 */
@Route(path = Router.ACTIVITY_READ, name = "阅读器核心")
public class ReadActivity extends AppCompatActivity {

  @Autowired
  protected Book book;

  @Autowired
  protected String bookName;

  private final int SHOW_WITHOUT_READ_SETTING_MENU = 0;
  private final int SHOW_WITH_READ_SETTING_MENU = 1;
  private final int GONE_MENU = 2;

  private ActivityReadBinding binding;

  private ReadCategoryAdapter readCategoryAdapter;

  private boolean isGone = true;

  private List<ReadBackground> readBackgrounds;

  private BookViewModel bookViewModel;

  private SplitDataLoader dataLoader;

  private Map<String, DownloadTask> downloadTasks = new HashMap<>();

  //接收电池信息和时间更新的广播
  private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
        int level = intent.getIntExtra("level", 0);
        binding.pvReadPage.updateBattery(level);
      }
      //监听分钟的变化
      else if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {
        binding.pvReadPage.updateTime();
      }
    }
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //////////////////////////////////////////////////////////////////////////////////////////
    //  初始化对象
    //////////////////////////////////////////////////////////////////////////////////////////
    ARouter.getInstance().inject(this);

    binding = DataBindingUtil.setContentView(ReadActivity.this, R.layout.activity_read);

    bookViewModel = ViewModelProviders.of(this).get(BookViewModel.class);

    //设置章节目录的RecyclerView
    readCategoryAdapter = new ReadCategoryAdapter(null, null);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    binding.readRvCatalog.setLayoutManager(linearLayoutManager);
    binding.readRvCatalog.setAdapter(readCategoryAdapter);

    //选中翻页动画
    AnimModeEnum animMode = ReadSettingManager.getAnimMode();
    switch (animMode) {
      case NONE:
        binding.readSettingRbNone.setChecked(true);
        break;
      case SIMULATION:
        binding.readSettingRbSimulation.setChecked(true);
        break;
      case COVER:
        binding.readSettingRbCover.setChecked(true);
        break;
      case SLIDE:
        binding.readSettingRbSlide.setChecked(true);
        break;
      case SCROLL:
        binding.readSettingRbScroll.setChecked(true);
        break;
        default:
          binding.readSettingRbCover.setChecked(true);
    }

    //阅读背景的RecyclerView
    ReadThemeEnum selectedReadTheme = ReadSettingManager.getReadTheme();
    readBackgrounds = new ArrayList<>();
    for (ReadThemeEnum readTheme : ReadThemeEnum.values()) {
      if (ReadThemeEnum.NIGHT.equals(readTheme)) continue;

      ReadBackground readBackground = new ReadBackground();
      readBackground.setReadTheme(readTheme);
      if (selectedReadTheme.equals(readTheme)) {
        readBackground.setSelected(true);
      } else {
        readBackground.setSelected(false);
      }
      readBackgrounds.add(readBackground);
    }
    ReadBgAdapter readBgAdapter = new ReadBgAdapter(readBackgrounds);
    binding.readSettingRvBg.setLayoutManager(new GridLayoutManager(this, readBackgrounds.size()));
    binding.readSettingRvBg.setAdapter(readBgAdapter);

    //注册广播
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
    intentFilter.addAction(Intent.ACTION_TIME_TICK);
    registerReceiver(mReceiver, intentFilter);

    //////////////////////////////////////////////////////////////////////////////////////////
    //  初始化数据
    //////////////////////////////////////////////////////////////////////////////////////////
    //这是书籍名
    if (!StringUtils.isTrimEmpty(bookName)) {
      binding.tvToolbarTitle.setText(bookName);
    }

    //设置变量数值
    binding.readDlSlide.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    binding.readSettingTvFontSize.setText(String.valueOf(binding.pvReadPage.getTextSize()));
    binding.readSettingCbFontDefault.setChecked(ReadSettingManager.isDefaultTextSize());

    //////////////////////////////////////////////////////////////////////////////////////////
    //  设置事件监听器
    //////////////////////////////////////////////////////////////////////////////////////////
    //中心区域点击触发
    binding.pvReadPage.setOnTouchListener(() -> toggleMenu());

    //上/下一章切换
    binding.readTvPreChapter.setOnClickListener(v -> {
      binding.pvReadPage.prevChapter();
    });
    binding.readTvNextChapter.setOnClickListener(v -> {
      binding.pvReadPage.nextChapter();
    });

    //目录
    binding.readTvCatalog.setOnClickListener(v -> {
      binding.readDlSlide.openDrawer(Gravity.START);
      toggleMenu();
    });

    //日间、夜间模式切换
    binding.readTvNightMode.setOnClickListener(v -> {
      binding.pvReadPage.toggleNightMode();
      if (binding.pvReadPage.isNightMode()) {
        binding.readTvNightMode.setText(getText(R.string.read_mode_morning));
        binding.readTvNightMode.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.mipmap.ic_morning), null, null);
      } else {
        binding.readTvNightMode.setText(getText(R.string.read_mode_night));
        binding.readTvNightMode.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.mipmap.ic_night), null, null);
      }
    });

    //显示/隐藏阅读设置菜单
    binding.readTvSetting.setOnClickListener(v -> switchMenuMode(SHOW_WITH_READ_SETTING_MENU));

    //设置系统亮度、自动亮度
    binding.readSettingSbBrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
      @Override
      public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
      }

      @Override
      public void onStartTrackingTouch(SeekBar seekBar) {
      }

      @Override
      public void onStopTrackingTouch(SeekBar seekBar) {
        int progress = seekBar.getProgress();
        BrightnessUtils.setBrightness(progress);
      }
    });
    binding.readSettingCbBrightnessAuto.setOnCheckedChangeListener((CompoundButton buttonView, boolean isChecked) -> {
      ReadSettingManager.setAutoBrightness(isChecked);
      if (isChecked) {
        binding.readSettingSbBrightness.setProgress(BrightnessUtils.getBrightness());
      }
    });
    if (ReadSettingManager.isBrightnessAuto()) {
      binding.readSettingCbBrightnessAuto.setChecked(true);
    } else {
      binding.readSettingCbBrightnessAuto.setChecked(false);
      binding.readSettingSbBrightness.setProgress(ReadSettingManager.getBrightness());
    }

    //设置字体大小、默认字体大小
    binding.readSettingTvFontMinus.setOnClickListener(v -> {
      int textSize = binding.pvReadPage.getTextSize() - 1;
      binding.pvReadPage.setTextSize(textSize);
      binding.readSettingTvFontSize.setText(String.valueOf(binding.pvReadPage.getTextSize()));
      binding.readSettingCbFontDefault.setChecked(textSize == ReadSettingManager.DEFAULT_READ_TEXT_SIZE);
    });
    binding.readSettingTvFontPlus.setOnClickListener(v -> {
      int textSize = binding.pvReadPage.getTextSize() + 1;
      binding.pvReadPage.setTextSize(textSize);
      binding.readSettingTvFontSize.setText(String.valueOf(binding.pvReadPage.getTextSize()));
      binding.readSettingCbFontDefault.setChecked(textSize == ReadSettingManager.DEFAULT_READ_TEXT_SIZE);
    });
    binding.readSettingCbFontDefault.setOnCheckedChangeListener((CompoundButton buttonView, boolean isChecked) -> {
      if (isChecked) {
        binding.pvReadPage.setTextSize(ReadSettingManager.DEFAULT_READ_TEXT_SIZE);
        binding.readSettingTvFontSize.setText(String.valueOf(binding.pvReadPage.getTextSize()));
      }
    });

    //设置翻页动画
    binding.readSettingRgPageMode.setOnCheckedChangeListener((RadioGroup group, int checkedId) -> {
      switch (checkedId) {
        case R.id.read_setting_rb_scroll:
          binding.pvReadPage.setAnimMode(AnimModeEnum.SCROLL);
          break;
        case R.id.read_setting_rb_simulation:
          binding.pvReadPage.setAnimMode(AnimModeEnum.SIMULATION);
          break;
        case R.id.read_setting_rb_cover:
          binding.pvReadPage.setAnimMode(AnimModeEnum.COVER);
          break;
        case R.id.read_setting_rb_slide:
          binding.pvReadPage.setAnimMode(AnimModeEnum.SLIDE);
          break;
        case R.id.read_setting_rb_none:
          binding.pvReadPage.setAnimMode(AnimModeEnum.NONE);
          break;
      }
      switchMenuMode(GONE_MENU);
    });

    //设置阅读背景色
    readBgAdapter.setOnItemClickListener((BaseQuickAdapter adapter, View view, int position) -> {
      for (ReadBackground r : readBackgrounds) {
        if (r.isSelected()) {
          r.setSelected(false);
          break;
        }
      }
      ReadBackground readBackground = readBackgrounds.get(position);
      readBackground.setSelected(true);
      binding.pvReadPage.setReadTheme(readBackground.getReadTheme());
      adapter.notifyDataSetChanged();
    });

    //目录（recyclerview列表）
    readCategoryAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
      @Override
      public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
        List<BookChapter> bookChapters = adapter.getData();
        //预下载的书籍
        handlePreDownload(bookChapters, position);

        binding.pvReadPage.skipChapter(position);

        readCategoryAdapter.setCurSelectedId(bookChapters.get(position).getId());
        readCategoryAdapter.notifyDataSetChanged();

        binding.readDlSlide.closeDrawers();
      }
    });

    //书籍章节变动监听
    bookViewModel.loadChaptersByBookId(book.getId()).observe(this, new Observer<Resource<List<BookChapter>>>() {
      @Override
      public void onChanged(@Nullable Resource<List<BookChapter>> listResource) {
        List<BookChapter> list = listResource.data;
        if(list != null && list.size() > 0) {
          if (readCategoryAdapter.getCurSelectedId() == null) {
            int position = book.getChapter()==null?0:book.getChapter();
            readCategoryAdapter.setCurSelectedId(list.get(position).getId());
            linearLayoutManager.scrollToPositionWithOffset(position,0);
            linearLayoutManager.setStackFromEnd(true);
          }
          //设置目录列表
          readCategoryAdapter.setNewData(list);

          if(dataLoader == null) {
            //转换为View专用的模型
            List<Chapter> chapters = new ArrayList<>(list.size());
            for(BookChapter bookChapter : list) {
              Chapter chapter = new Chapter();
              chapter.setTitle(bookChapter.getTitle());
              chapter.setPath(bookChapter.getFilePath());
              chapters.add(chapter);
            }

            int position = book.getChapter()==null?0:book.getChapter();

            handlePreDownload(list, position);

            //书页翻动监听器
            dataLoader = new SplitDataLoader(chapters, book.getChapter(), book.getPage());
            dataLoader.setOnPageChangeListener(new DataLoader.OnPageChangeListener() {

              private int chapter = 0;

              @Override
              public void pageChange(int chapter, int page) {
                if(this.chapter == chapter) {
                  return;
                }
                this.chapter = chapter;

                book.setPage(page);
                book.setChapter(chapter);
                bookViewModel.updateBookChapterAndPage(book);

                BookChapter bookChapter = list.get(chapter);
                readCategoryAdapter.setCurSelectedId(bookChapter.getId());
                readCategoryAdapter.notifyDataSetChanged();

                handlePreDownload(list, chapter);
              }

              @Override
              public void chapterNotFound(int chapter) {
                BookChapter bookChapter = list.get(chapter);
                LogUtils.d("找不到章节："+ bookChapter.getTitle());
                boolean isDownloading = downloadFile(bookChapter.getPath(), 1, chapter);
                if(isDownloading) {
                  new CountDownTimer(5000, 500) {
                    private boolean isFileExist = false;
                    @Override
                    public void onTick(long millisUntilFinished) {
                      if(bookChapter.isFileExist()) {
                        isFileExist = true;
                        this.onFinish();
                      }
                    }

                    @Override
                    public void onFinish() {
                      if(isFileExist) {
                        LogUtils.d("下载完毕，加载");
                        binding.pvReadPage.notifyChapterIsExit(chapter);
                      }
                    }
                  }.start();
                }
              }
            });
            binding.pvReadPage.setDataLoader(dataLoader);
          }
        }
      }
    });
  }

  //菜单
  private void toggleMenu() {
    if (isGone) {
      switchMenuMode(SHOW_WITHOUT_READ_SETTING_MENU);
      isGone = false;
    } else {
      switchMenuMode(GONE_MENU);
      isGone = true;
    }
  }

  /**
   * 设置菜单显示模式
   *
   * @param mode
   */
  private void switchMenuMode(int mode) {
    switch (mode) {
      case SHOW_WITH_READ_SETTING_MENU:
        binding.readAblTopMenu.setVisibility(View.VISIBLE);
        binding.readSettingLlMenu.setVisibility(View.VISIBLE);
        binding.readLlBottomMenu.setVisibility(View.GONE);
        //binding.readTvPageTip.setVisibility(View.GONE);
        break;
      case SHOW_WITHOUT_READ_SETTING_MENU:
        binding.readAblTopMenu.setVisibility(View.VISIBLE);
        //binding.readTvPageTip.setVisibility(View.VISIBLE);
        binding.readLlBottomMenu.setVisibility(View.VISIBLE);
        break;
      default:
        binding.readAblTopMenu.setVisibility(View.GONE);
        //binding.readTvPageTip.setVisibility(View.GONE);
        binding.readLlBottomMenu.setVisibility(View.GONE);
        binding.readSettingLlMenu.setVisibility(View.GONE);
    }
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();

    unregisterReceiver(mReceiver);
  }

  /**
   * 下载任务 1-reload视图 0-仅下载
   * @param path
   * @param operation
   * @return true - 正在下载 false-开始异步下载
   */
  private boolean downloadFile(String path, int operation, int chapter) {
    if(downloadTasks.size() > 0) {
      for(String prevTaskPath : downloadTasks.keySet()) {
        if(prevTaskPath.equals(path)) {
          LogUtils.d("任务重复：被移除");
          return true;
        }
      }
    }

    PermissionUtils.permission(Manifest.permission.WRITE_EXTERNAL_STORAGE).callback(new PermissionUtils.SimpleCallback() {
      @Override
      public void onGranted() {
        String cachePath = PathUtils.getExternalAppCachePath();
        DownloadTask task = new DownloadTask.Builder(path, new File(cachePath)).build();
        downloadTasks.put(path, task);
        task.enqueue(new DownloadListener2() {
          @Override
          public void taskStart(@NonNull DownloadTask task) {
            LogUtils.d("任务开始"+this.toString());
          }

          @Override
          public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause) {
            LogUtils.d("任务结束"+this.toString());
            downloadTasks.remove(path);
            if (cause.equals(EndCause.COMPLETED)) {
              if(operation == 1) {
                binding.pvReadPage.notifyChapterIsExit(chapter);
              }
            } else {
              LogUtils.d("发生了异常", realCause, cause.toString());
            }
          }
        });
      }

      @Override
      public void onDenied() {
        ToastUtils.showShort("没有写缓存的权限");
      }
    }).request();

    return false;
  }

  /**
   * 预先下载指定范围的书籍
   * @param bookChapters
   * @param position
   */
  private void handlePreDownload(List<BookChapter> bookChapters, int position){
    //预下载的书籍
    List<BookChapter> targetChapters = new ArrayList<>(5);
    targetChapters.add(bookChapters.get(position));
    if(position - 1 >= 0) {
      targetChapters.add(bookChapters.get(position - 1));
    }
    if(position + 1 < bookChapters.size()) {
      targetChapters.add(bookChapters.get(position + 1));
    }
    if(position - 2 >= 0) {
      targetChapters.add(bookChapters.get(position - 2));
    }
    if(position + 2 < bookChapters.size()) {
      targetChapters.add(bookChapters.get(position + 2));
    }

    for(BookChapter bookChapter : targetChapters) {
      if(!bookChapter.isFileExist()) {
        downloadFile(bookChapter.getPath(), 0, -1);
      }
    }
  }

  @Override
  protected void onPause() {
    super.onPause();
    MobclickAgent.onPageEnd("阅读器核心");
    MobclickAgent.onPause(this);
  }

  @Override
  protected void onResume() {
    super.onResume();
    MobclickAgent.onPageStart("阅读器核心");
    MobclickAgent.onResume(this);
  }
}
